package com.yohann.boot.util;

import com.yohann.boot.common.annotation.ConvertEnum;
import com.yohann.boot.common.annotation.EnableConvert;
import com.yohann.boot.common.enums.TranslationEnum;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Objects;

/**
 * 枚举值转化工具
 *
 * @author Yeung Wah
 * @since 2021/9/17
 */
@Slf4j
public class ConvertUtils {

    private ConvertUtils() {
    }

    public static <T> void convertEnums(T t) {
        //对象为空则直接结束
        if (Objects.isNull(t)) {
            return;
        }

        for (Class<?> clazz = t.getClass(); !clazz.equals(Object.class); clazz = clazz.getSuperclass()) {
            //开启翻译
            if (clazz.isAnnotationPresent(EnableConvert.class)) {
                Field[] fields = clazz.getDeclaredFields();
                Field.setAccessible(fields, true);

                for (Field field : fields) {
                    //枚举翻译
                    ConvertEnum convertEnum = field.getAnnotation(ConvertEnum.class);
                    if (Objects.nonNull(convertEnum)) {
                        //获取注解信息
                        Class<? extends TranslationEnum> enumClazz = convertEnum.clazz();

                        try {
                            //获取需要翻译的字段值
                            Field codeField = clazz.getDeclaredField(convertEnum.codeField());
                            codeField.setAccessible(true);
                            Object code = codeField.get(t);

                            //获取枚举实例对象 獲取映射字段
                            if (!enumClazz.isEnum()) {
                                throw new RuntimeException(enumClazz.getName() + "非枚举类型");
                            } else if (enumClazz.getEnumConstants().length == 0) {
                                throw new RuntimeException(enumClazz.getName() + "无实例");
                            }
                            TranslationEnum translationEnum = enumClazz.getEnumConstants()[0];
                            if (Objects.nonNull(translationEnum)) {
                                Object value = translationEnum.getValue(code);
                                field.set(t, value);
                            }
                        } catch (Exception e) {
                            LogUtils.debug("convert exception:" + e.getMessage(), e);
                        }
                    }
                }
            }
        }
    }

    public static <T> void convertEnums(List<T> list) {
        //集合为空则直接结束
        if (list.isEmpty()) {
            return;
        }

        list.forEach(ConvertUtils::convertEnums);
    }

}